const { User, Invitation, PointsTransaction, ShareStatistics } = require('../models')
const logger = require('../utils/logger')

class InviteAnalyticsService {
  /**
   * 获取邀请数据分析报告
   * @param {Object} options - 查询选项
   * @returns {Promise<Object>} 分析报告
   */
  static async getInviteAnalytics(options = {}) {
    try {
      const {
        period = 'month', // day, week, month, year, all
        startDate,
        endDate
      } = options

      const { Op } = require('sequelize')
      const sequelize = require('../config/database')

      // 构建时间范围
      const timeRange = this.buildTimeRange(period, startDate, endDate)

      // 基础统计
      const basicStats = await this.getBasicStats(timeRange)
      
      // 趋势分析
      const trendData = await this.getTrendData(period, timeRange)
      
      // 转化漏斗
      const conversionFunnel = await this.getConversionFunnel(timeRange)
      
      // 用户分层分析
      const userSegmentation = await this.getUserSegmentation(timeRange)
      
      // 渠道效果分析
      const channelAnalysis = await this.getChannelAnalysis(timeRange)

      return {
        period,
        timeRange,
        basicStats,
        trendData,
        conversionFunnel,
        userSegmentation,
        channelAnalysis,
        generatedAt: new Date().toISOString()
      }
    } catch (error) {
      logger.error('获取邀请数据分析失败:', error)
      throw error
    }
  }

  /**
   * 构建时间范围
   * @param {string} period - 时间周期
   * @param {string} startDate - 开始日期
   * @param {string} endDate - 结束日期
   * @returns {Object} 时间范围
   */
  static buildTimeRange(period, startDate, endDate) {
    const now = new Date()
    let start, end = now

    if (startDate && endDate) {
      start = new Date(startDate)
      end = new Date(endDate)
    } else {
      switch (period) {
        case 'day':
          start = new Date(now.getFullYear(), now.getMonth(), now.getDate())
          break
        case 'week':
          start = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
          break
        case 'month':
          start = new Date(now.getFullYear(), now.getMonth(), 1)
          break
        case 'year':
          start = new Date(now.getFullYear(), 0, 1)
          break
        default:
          start = null
      }
    }

    return { start, end }
  }

  /**
   * 获取基础统计数据
   * @param {Object} timeRange - 时间范围
   * @returns {Promise<Object>} 基础统计
   */
  static async getBasicStats(timeRange) {
    try {
      const { Op } = require('sequelize')
      const sequelize = require('../config/database')

      let whereClause = {}
      if (timeRange.start) {
        whereClause.created_at = {
          [Op.between]: [timeRange.start, timeRange.end]
        }
      }

      // 邀请统计
      const inviteStats = await Invitation.findOne({
        where: whereClause,
        attributes: [
          [sequelize.fn('COUNT', sequelize.col('id')), 'total_invites'],
          [sequelize.fn('COUNT', sequelize.literal('CASE WHEN status = 1 THEN 1 END')), 'successful_invites'],
          [sequelize.fn('COUNT', sequelize.literal('CASE WHEN first_consume_time IS NOT NULL THEN 1 END')), 'converted_invites'],
          [sequelize.fn('SUM', sequelize.col('total_reward_points')), 'total_rewards']
        ]
      })

      // 活跃邀请人统计
      const activeInviters = await Invitation.findOne({
        where: whereClause,
        attributes: [
          [sequelize.fn('COUNT', sequelize.fn('DISTINCT', sequelize.col('inviter_id'))), 'active_inviters']
        ]
      })

      // 新用户统计
      let newUserWhereClause = {}
      if (timeRange.start) {
        newUserWhereClause.created_at = {
          [Op.between]: [timeRange.start, timeRange.end]
        }
      }

      const newUserStats = await User.findOne({
        where: newUserWhereClause,
        attributes: [
          [sequelize.fn('COUNT', sequelize.col('id')), 'total_new_users'],
          [sequelize.fn('COUNT', sequelize.literal('CASE WHEN inviter_id IS NOT NULL THEN 1 END')), 'invited_new_users']
        ]
      })

      const totalInvites = parseInt(inviteStats.getDataValue('total_invites')) || 0
      const successfulInvites = parseInt(inviteStats.getDataValue('successful_invites')) || 0
      const convertedInvites = parseInt(inviteStats.getDataValue('converted_invites')) || 0
      const totalNewUsers = parseInt(newUserStats.getDataValue('total_new_users')) || 0
      const invitedNewUsers = parseInt(newUserStats.getDataValue('invited_new_users')) || 0

      return {
        totalInvites,
        successfulInvites,
        convertedInvites,
        totalRewards: parseFloat(inviteStats.getDataValue('total_rewards')) || 0,
        activeInviters: parseInt(activeInviters.getDataValue('active_inviters')) || 0,
        totalNewUsers,
        invitedNewUsers,
        // 计算转化率
        inviteSuccessRate: totalInvites > 0 ? Math.round((successfulInvites / totalInvites) * 100) : 0,
        conversionRate: successfulInvites > 0 ? Math.round((convertedInvites / successfulInvites) * 100) : 0,
        inviteUserRate: totalNewUsers > 0 ? Math.round((invitedNewUsers / totalNewUsers) * 100) : 0
      }
    } catch (error) {
      logger.error('获取基础统计失败:', error)
      throw error
    }
  }

  /**
   * 获取趋势数据
   * @param {string} period - 时间周期
   * @param {Object} timeRange - 时间范围
   * @returns {Promise<Array>} 趋势数据
   */
  static async getTrendData(period, timeRange) {
    try {
      const { Op } = require('sequelize')
      const sequelize = require('../config/database')

      let dateFormat, groupBy
      switch (period) {
        case 'day':
          dateFormat = '%Y-%m-%d %H:00:00'
          groupBy = sequelize.fn('DATE_FORMAT', sequelize.col('created_at'), '%Y-%m-%d %H:00:00')
          break
        case 'week':
        case 'month':
          dateFormat = '%Y-%m-%d'
          groupBy = sequelize.fn('DATE_FORMAT', sequelize.col('created_at'), '%Y-%m-%d')
          break
        case 'year':
          dateFormat = '%Y-%m'
          groupBy = sequelize.fn('DATE_FORMAT', sequelize.col('created_at'), '%Y-%m')
          break
        default:
          dateFormat = '%Y-%m'
          groupBy = sequelize.fn('DATE_FORMAT', sequelize.col('created_at'), '%Y-%m')
      }

      let whereClause = {}
      if (timeRange.start) {
        whereClause.created_at = {
          [Op.between]: [timeRange.start, timeRange.end]
        }
      }

      const trendData = await Invitation.findAll({
        where: whereClause,
        attributes: [
          [groupBy, 'date'],
          [sequelize.fn('COUNT', sequelize.col('id')), 'invite_count'],
          [sequelize.fn('COUNT', sequelize.literal('CASE WHEN status = 1 THEN 1 END')), 'success_count'],
          [sequelize.fn('COUNT', sequelize.literal('CASE WHEN first_consume_time IS NOT NULL THEN 1 END')), 'convert_count'],
          [sequelize.fn('SUM', sequelize.col('total_reward_points')), 'reward_points']
        ],
        group: [groupBy],
        order: [[groupBy, 'ASC']]
      })

      return trendData.map(item => ({
        date: item.getDataValue('date'),
        inviteCount: parseInt(item.getDataValue('invite_count')) || 0,
        successCount: parseInt(item.getDataValue('success_count')) || 0,
        convertCount: parseInt(item.getDataValue('convert_count')) || 0,
        rewardPoints: parseFloat(item.getDataValue('reward_points')) || 0
      }))
    } catch (error) {
      logger.error('获取趋势数据失败:', error)
      throw error
    }
  }

  /**
   * 获取转化漏斗数据
   * @param {Object} timeRange - 时间范围
   * @returns {Promise<Object>} 转化漏斗
   */
  static async getConversionFunnel(timeRange) {
    try {
      const { Op } = require('sequelize')
      const sequelize = require('../config/database')

      let whereClause = {}
      if (timeRange.start) {
        whereClause.created_at = {
          [Op.between]: [timeRange.start, timeRange.end]
        }
      }

      // 分享统计
      const shareStats = await ShareStatistics.findOne({
        where: timeRange.start ? {
          created_at: {
            [Op.between]: [timeRange.start, timeRange.end]
          }
        } : {},
        attributes: [
          [sequelize.fn('COUNT', sequelize.col('id')), 'total_shares'],
          [sequelize.fn('SUM', sequelize.col('click_count')), 'total_clicks']
        ]
      })

      // 邀请统计
      const inviteStats = await Invitation.findOne({
        where: whereClause,
        attributes: [
          [sequelize.fn('COUNT', sequelize.col('id')), 'total_invites'],
          [sequelize.fn('COUNT', sequelize.literal('CASE WHEN status = 1 THEN 1 END')), 'successful_invites'],
          [sequelize.fn('COUNT', sequelize.literal('CASE WHEN first_consume_time IS NOT NULL THEN 1 END')), 'converted_invites']
        ]
      })

      const totalShares = parseInt(shareStats.getDataValue('total_shares')) || 0
      const totalClicks = parseInt(shareStats.getDataValue('total_clicks')) || 0
      const totalInvites = parseInt(inviteStats.getDataValue('total_invites')) || 0
      const successfulInvites = parseInt(inviteStats.getDataValue('successful_invites')) || 0
      const convertedInvites = parseInt(inviteStats.getDataValue('converted_invites')) || 0

      return {
        steps: [
          {
            name: '分享',
            count: totalShares,
            rate: 100,
            description: '用户分享邀请链接'
          },
          {
            name: '点击',
            count: totalClicks,
            rate: totalShares > 0 ? Math.round((totalClicks / totalShares) * 100) : 0,
            description: '好友点击邀请链接'
          },
          {
            name: '注册',
            count: totalInvites,
            rate: totalClicks > 0 ? Math.round((totalInvites / totalClicks) * 100) : 0,
            description: '好友完成注册'
          },
          {
            name: '激活',
            count: successfulInvites,
            rate: totalInvites > 0 ? Math.round((successfulInvites / totalInvites) * 100) : 0,
            description: '邀请关系建立成功'
          },
          {
            name: '转化',
            count: convertedInvites,
            rate: successfulInvites > 0 ? Math.round((convertedInvites / successfulInvites) * 100) : 0,
            description: '好友完成首次消费'
          }
        ],
        overallConversionRate: totalShares > 0 ? Math.round((convertedInvites / totalShares) * 100) : 0
      }
    } catch (error) {
      logger.error('获取转化漏斗失败:', error)
      throw error
    }
  }

  /**
   * 获取用户分层分析
   * @param {Object} timeRange - 时间范围
   * @returns {Promise<Object>} 用户分层
   */
  static async getUserSegmentation(timeRange) {
    try {
      const { Op } = require('sequelize')
      const sequelize = require('../config/database')

      let whereClause = {}
      if (timeRange.start) {
        whereClause.created_at = {
          [Op.between]: [timeRange.start, timeRange.end]
        }
      }

      // 按邀请数量分层
      const inviteCountSegments = await Invitation.findAll({
        where: whereClause,
        attributes: [
          'inviter_id',
          [sequelize.fn('COUNT', sequelize.col('id')), 'invite_count']
        ],
        group: ['inviter_id'],
        having: sequelize.literal('invite_count > 0')
      })

      const segments = {
        newbie: 0,      // 1-2个邀请
        active: 0,      // 3-9个邀请
        power: 0,       // 10-29个邀请
        super: 0,       // 30+个邀请
        total: 0
      }

      inviteCountSegments.forEach(item => {
        const count = parseInt(item.getDataValue('invite_count'))
        segments.total++
        
        if (count >= 30) {
          segments.super++
        } else if (count >= 10) {
          segments.power++
        } else if (count >= 3) {
          segments.active++
        } else {
          segments.newbie++
        }
      })

      // 按会员等级分层
      const levelSegments = await User.findAll({
        attributes: [
          'memberLevel',
          [sequelize.fn('COUNT', sequelize.col('id')), 'user_count']
        ],
        include: [{
          model: Invitation,
          as: 'invitees', // 这里需要确保User模型中有正确的关联
          where: whereClause,
          required: true
        }],
        group: ['memberLevel']
      })

      return {
        byInviteCount: {
          segments,
          distribution: {
            newbie: segments.total > 0 ? Math.round((segments.newbie / segments.total) * 100) : 0,
            active: segments.total > 0 ? Math.round((segments.active / segments.total) * 100) : 0,
            power: segments.total > 0 ? Math.round((segments.power / segments.total) * 100) : 0,
            super: segments.total > 0 ? Math.round((segments.super / segments.total) * 100) : 0
          }
        },
        byMemberLevel: levelSegments.map(item => ({
          level: item.memberLevel,
          count: parseInt(item.getDataValue('user_count')),
          percentage: segments.total > 0 ? Math.round((parseInt(item.getDataValue('user_count')) / segments.total) * 100) : 0
        }))
      }
    } catch (error) {
      logger.error('获取用户分层分析失败:', error)
      throw error
    }
  }

  /**
   * 获取渠道效果分析
   * @param {Object} timeRange - 时间范围
   * @returns {Promise<Array>} 渠道分析
   */
  static async getChannelAnalysis(timeRange) {
    try {
      const { Op } = require('sequelize')
      const sequelize = require('../config/database')

      let whereClause = {}
      if (timeRange.start) {
        whereClause.created_at = {
          [Op.between]: [timeRange.start, timeRange.end]
        }
      }

      const channelStats = await ShareStatistics.findAll({
        where: whereClause,
        attributes: [
          'share_channel',
          [sequelize.fn('COUNT', sequelize.col('id')), 'share_count'],
          [sequelize.fn('SUM', sequelize.col('click_count')), 'total_clicks'],
          [sequelize.fn('SUM', sequelize.col('register_count')), 'total_registers'],
          [sequelize.fn('AVG', sequelize.col('click_count')), 'avg_clicks_per_share'],
          [sequelize.fn('COUNT', sequelize.fn('DISTINCT', sequelize.col('user_id'))), 'unique_sharers']
        ],
        group: ['share_channel'],
        order: [[sequelize.fn('SUM', sequelize.col('register_count')), 'DESC']]
      })

      return channelStats.map((item, index) => {
        const shareCount = parseInt(item.getDataValue('share_count')) || 0
        const totalClicks = parseInt(item.getDataValue('total_clicks')) || 0
        const totalRegisters = parseInt(item.getDataValue('total_registers')) || 0
        const uniqueSharers = parseInt(item.getDataValue('unique_sharers')) || 0

        return {
          rank: index + 1,
          channel: item.share_channel,
          channelName: this.getChannelName(item.share_channel),
          shareCount,
          totalClicks,
          totalRegisters,
          uniqueSharers,
          avgClicksPerShare: parseFloat(item.getDataValue('avg_clicks_per_share')) || 0,
          clickRate: shareCount > 0 ? Math.round((totalClicks / shareCount) * 100) / 100 : 0,
          conversionRate: totalClicks > 0 ? Math.round((totalRegisters / totalClicks) * 100) : 0,
          efficiency: shareCount > 0 ? Math.round((totalRegisters / shareCount) * 100) / 100 : 0
        }
      })
    } catch (error) {
      logger.error('获取渠道效果分析失败:', error)
      throw error
    }
  }

  /**
   * 获取渠道中文名称
   * @param {string} channel - 渠道代码
   * @returns {string} 中文名称
   */
  static getChannelName(channel) {
    const channelNames = {
      wechat: '微信好友',
      moments: '朋友圈',
      qq: 'QQ好友',
      qzone: 'QQ空间',
      weibo: '微博',
      copy: '复制链接',
      qrcode: '二维码'
    }
    return channelNames[channel] || channel
  }

  /**
   * 获取推广大使列表
   * @param {Object} options - 查询选项
   * @returns {Promise<Array>} 推广大使列表
   */
  static async getPromotionAmbassadors(options = {}) {
    try {
      const {
        minInvites = 20,
        minConversionRate = 30,
        limit = 50
      } = options

      const { Op } = require('sequelize')
      const sequelize = require('../config/database')

      const ambassadors = await Invitation.findAll({
        attributes: [
          'inviter_id',
          [sequelize.fn('COUNT', sequelize.col('id')), 'total_invites'],
          [sequelize.fn('COUNT', sequelize.literal('CASE WHEN first_consume_time IS NOT NULL THEN 1 END')), 'converted_invites'],
          [sequelize.fn('SUM', sequelize.col('total_reward_points')), 'total_rewards']
        ],
        include: [{
          model: User,
          as: 'inviter',
          attributes: ['id', 'nickname', 'avatar', 'memberLevel', 'created_at']
        }],
        group: ['inviter_id'],
        having: sequelize.literal(`COUNT(id) >= ${minInvites}`),
        order: [[sequelize.fn('COUNT', sequelize.col('id')), 'DESC']],
        limit
      })

      return ambassadors
        .map(item => {
          const totalInvites = parseInt(item.getDataValue('total_invites'))
          const convertedInvites = parseInt(item.getDataValue('converted_invites'))
          const conversionRate = totalInvites > 0 ? Math.round((convertedInvites / totalInvites) * 100) : 0

          return {
            user: item.inviter,
            totalInvites,
            convertedInvites,
            conversionRate,
            totalRewards: parseFloat(item.getDataValue('total_rewards')) || 0,
            isQualified: conversionRate >= minConversionRate
          }
        })
        .filter(ambassador => ambassador.isQualified)
        .sort((a, b) => b.conversionRate - a.conversionRate)
    } catch (error) {
      logger.error('获取推广大使列表失败:', error)
      throw error
    }
  }

  /**
   * 生成邀请效果报表
   * @param {Object} options - 报表选项
   * @returns {Promise<Object>} 报表数据
   */
  static async generateInviteReport(options = {}) {
    try {
      const {
        period = 'month',
        format = 'summary' // summary, detailed
      } = options

      const analytics = await this.getInviteAnalytics({ period })
      const ambassadors = await this.getPromotionAmbassadors()

      const report = {
        title: `邀请推广效果报告 - ${period}`,
        generatedAt: new Date().toISOString(),
        period: analytics.period,
        timeRange: analytics.timeRange,
        
        // 核心指标
        keyMetrics: {
          totalInvites: analytics.basicStats.totalInvites,
          successRate: analytics.basicStats.inviteSuccessRate,
          conversionRate: analytics.basicStats.conversionRate,
          totalRewards: analytics.basicStats.totalRewards,
          activeInviters: analytics.basicStats.activeInviters
        },
        
        // 趋势摘要
        trendSummary: {
          dataPoints: analytics.trendData.length,
          peakDay: this.findPeakDay(analytics.trendData),
          growthRate: this.calculateGrowthRate(analytics.trendData)
        },
        
        // 渠道效果排名
        topChannels: analytics.channelAnalysis.slice(0, 3),
        
        // 推广大使数量
        ambassadorCount: ambassadors.length,
        
        // 建议和洞察
        insights: this.generateInsights(analytics, ambassadors)
      }

      if (format === 'detailed') {
        report.detailedAnalytics = analytics
        report.ambassadorList = ambassadors
      }

      return report
    } catch (error) {
      logger.error('生成邀请效果报表失败:', error)
      throw error
    }
  }

  /**
   * 查找峰值日期
   * @param {Array} trendData - 趋势数据
   * @returns {Object} 峰值信息
   */
  static findPeakDay(trendData) {
    if (!trendData || trendData.length === 0) return null

    const peak = trendData.reduce((max, current) => 
      current.inviteCount > max.inviteCount ? current : max
    )

    return {
      date: peak.date,
      inviteCount: peak.inviteCount
    }
  }

  /**
   * 计算增长率
   * @param {Array} trendData - 趋势数据
   * @returns {number} 增长率百分比
   */
  static calculateGrowthRate(trendData) {
    if (!trendData || trendData.length < 2) return 0

    const first = trendData[0].inviteCount
    const last = trendData[trendData.length - 1].inviteCount

    if (first === 0) return last > 0 ? 100 : 0
    return Math.round(((last - first) / first) * 100)
  }

  /**
   * 生成洞察和建议
   * @param {Object} analytics - 分析数据
   * @param {Array} ambassadors - 推广大使列表
   * @returns {Array} 洞察列表
   */
  static generateInsights(analytics, ambassadors) {
    const insights = []

    // 转化率分析
    if (analytics.basicStats.conversionRate < 20) {
      insights.push({
        type: 'warning',
        title: '转化率偏低',
        description: `当前转化率为${analytics.basicStats.conversionRate}%，建议优化邀请奖励机制或用户引导流程`
      })
    } else if (analytics.basicStats.conversionRate > 50) {
      insights.push({
        type: 'success',
        title: '转化率优秀',
        description: `当前转化率达到${analytics.basicStats.conversionRate}%，表现优异`
      })
    }

    // 渠道效果分析
    const topChannel = analytics.channelAnalysis[0]
    if (topChannel) {
      insights.push({
        type: 'info',
        title: '最佳推广渠道',
        description: `${topChannel.channelName}是效果最好的推广渠道，转化率达到${topChannel.conversionRate}%`
      })
    }

    // 推广大使分析
    if (ambassadors.length > 0) {
      insights.push({
        type: 'success',
        title: '推广大使表现',
        description: `当前有${ambassadors.length}位推广大使，建议给予特殊奖励和权益`
      })
    } else {
      insights.push({
        type: 'suggestion',
        title: '培养推广大使',
        description: '建议设立推广大使计划，激励高质量邀请用户'
      })
    }

    return insights
  }
}

module.exports = InviteAnalyticsService